package com.bzchao.doublecamera;

import android.content.Context;
import android.graphics.Bitmap;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraManager;
import android.os.Bundle;
import android.util.Log;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;

import com.bzchao.camera.R;
import com.bzchao.camera.encode.MediaVideoBufferEncoder;
import com.bzchao.doublecamera.base.BaseActivity;
import com.bzchao.doublecamera.base.BaseConstants;
import com.bzchao.doublecamera.base.ErrorDialog;
import com.bzchao.doublecamera.handler.CameraHandler;
import com.bzchao.doublecamera.utils.BitmapUtils;
import com.bzchao.doublecamera.utils.TimeStaticUtils;

import java.nio.ByteBuffer;
import java.util.Timer;
import java.util.TimerTask;

public class MyCameraActivity extends BaseActivity {

    private static ImageView mImageView;

    private static final String TAG = "MyCameraActivity";

    private static final String FRAGMENT_DIALOG = "dialog";

    private static BaseActivity baseActivity;

    private static CameraOneHandler cameraOneHandler0;
    private static CameraOneHandler cameraOneHandler1;

    private Object mVideoEncoderObject = new Object();
    private static Object mSync = new Object();
    /**
     * 需要合成的图片
     */
    private static Bitmap[] bitmaps = new Bitmap[2];

    private static Timer timer;

    private CameraManager manager;
    private String mCameraId0, mCameraId1;
    ;
    private TimerTask timeoutTask;

    private CameraHandler mCameraHandler;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my_camera);
        baseActivity = this;
        initView();
        Log.isLoggable("qdgralloc", Log.WARN);

        manager = (CameraManager) this.getSystemService(Context.CAMERA_SERVICE);

        AutoFitTextureView textureView0 = this.findViewById(R.id.texture);
        cameraOneHandler0 = new CameraOneHandler(this, textureView0, manager, mCameraId0, bitmap -> bitmaps[0] = bitmap);
        cameraOneHandler0.setViewSize(BaseConstants.DEFAULT_WIDTH, BaseConstants.DEFAULT_HEIGHT);
        AutoFitTextureView textureView1 = this.findViewById(R.id.texture_two);
        cameraOneHandler1 = new CameraOneHandler(this, textureView1, manager, mCameraId1, bitmap -> bitmaps[1] = bitmap);
        cameraOneHandler1.setViewSize(BaseConstants.DEFAULT_WIDTH / 3, BaseConstants.DEFAULT_HEIGHT / 3);
        startUnionImageTask();
    }

    /**
     * 初始化
     */
    private void initView() {
        loanCameraId();
        mImageView = findViewById(R.id.texture_all);

        //初始化按钮
        Button intiBtn = findViewById(R.id.init_btn);
        //暂时先隐藏初始化按钮
        //intiBtn.setVisibility(View.INVISIBLE);
        intiBtn.setOnClickListener(v -> {
            if (mCameraHandler == null) {
                runOnUiThread(() -> {
                    startVideo();
                });
            } else {
                runOnUiThread(() -> {
                    stopVideo();
                });
            }
        });

        //主摄像按钮
        findViewById(R.id.cam_btn_01).setOnClickListener(v -> {
            cameraOneHandler0.initView();
        });
        //副摄像按钮
        findViewById(R.id.cam_btn_02).setOnClickListener(v -> {
            cameraOneHandler1.initView();
        });
    }

    @Override
    public void onResume() {
        super.onResume();
        manager = (CameraManager) this.getSystemService(Context.CAMERA_SERVICE);
    }

    public void loanCameraId() {
        CameraManager manager = (CameraManager) this.getSystemService(Context.CAMERA_SERVICE);
        try {
            String[] ids = manager.getCameraIdList();
            //获取可用摄像头列表
            for (String cameraId : ids) {
                //获取相机的相关参数
                CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);
                // 不使用前置摄像头。
                Integer facing = characteristics.get(CameraCharacteristics.LENS_FACING);
                if (facing != null && facing == CameraCharacteristics.LENS_FACING_BACK) {
                    mCameraId0 = cameraId;
                } else {
                    mCameraId1 = cameraId;
                }
            }
        } catch (CameraAccessException e) {
            Log.w("初始化摄像头失败", e);
        } catch (NullPointerException e) {
            Log.w("初始化摄像头失败", e);
            //不支持Camera2API
            ErrorDialog errorDialog = ErrorDialog.newInstance(getString(R.string.camera_error));
            errorDialog.show(this.getFragmentManager(), FRAGMENT_DIALOG);
        }
    }


    private void startUnionImageTask() {
        timeoutTask = new TimerTask() {
            @Override
            public void run() {
                //之是渲染当前图片
                if (!isShowPreview(bitmaps)) {
                    return;
                }
                if (bitmaps[1] == null) {
                    //前置图片为空，则只渲染背景图
                    baseActivity.runOnUiThread(() -> {
                        mImageView.setImageBitmap(bitmaps[0]);
                    });
                } else {
                    //显示在界面上
                    baseActivity.runOnUiThread(() -> {
                        Bitmap bitmap = BitmapUtils.toConformBitmap2(bitmaps[0], bitmaps[1]);
                        Bitmap bitmap2 = BitmapUtils.addTimeWatermark(bitmap);
                        mImageView.setImageBitmap(bitmap2);
                    });

                    //生成视频
                    // Bitmap bitmap = BitmapUtils.toConformBitmap2(bitmaps[0], bitmaps[1]);
                    Bitmap bitmap = bitmaps[0];
                    if (mCameraHandler == null) {
                        return;
                    }
                    MediaVideoBufferEncoder mVideoEncoder = mCameraHandler.getmVideoEncoder();

                    if (mVideoEncoder != null) {
                        //待优化，每张图片处理时间为5-6秒
                        TimeStaticUtils start = TimeStaticUtils.start();
                        Bitmap transformBitmap = BitmapUtils.getTransformBitmap(bitmap);
                        Log.w("图片类型", transformBitmap.getConfig().name());
                        byte[] nv21 = BitmapUtils.bitmapToNv21(transformBitmap, transformBitmap.getWidth(), transformBitmap.getHeight());

                        Log.w("mIFrameCallback处理时间3", start.endAndGetRunTime() + "");
                        ByteBuffer byteBuffer = ByteBuffer.wrap(nv21);
                        byteBuffer.clear();
                        Log.w("mIFrameCallback处理时间4", start.endAndGetRunTime() + "");
                        mVideoEncoder.frameAvailableSoon();
                        mVideoEncoder.encode(byteBuffer);
                    }
                }
            }
        };
        timer = new Timer();
        timer.schedule(timeoutTask, 0, 200);

    }

    //记录上一次渲染的图像（与最新的相同则不再重新渲染）
    private static Object[] previewObject = new Object[2];

    private static boolean isShowPreview(Bitmap[] bitmaps) {
        // 0为背景，背景为空不渲染
        if (bitmaps[0] == null) {
            return false;
        }
        //相同的图片对象则不再重现渲染
        if (previewObject[0] == bitmaps[0] && previewObject[1] == bitmaps[1]) {
            return false;
        }

        // 重新渲染时保存渲染的图片
        previewObject[0] = bitmaps[0];
        previewObject[1] = bitmaps[1];
        return true;
    }

    private void startVideo() {
        if (true) {
            Toast.makeText(baseActivity, "暂时不可用", Toast.LENGTH_SHORT).show();
            return;
        }

        if (bitmaps[0] == null) {
            Toast.makeText(baseActivity, "请打开摄像头", Toast.LENGTH_SHORT).show();
            return;
        }
        startUnionImageTask();

        handleStartRecording();
        Toast.makeText(baseActivity, "启动录像", Toast.LENGTH_SHORT).show();
    }

    private void stopVideo() {
        synchronized (mVideoEncoderObject) {
            timer.cancel();
            handleStopRecording();
            Toast.makeText(baseActivity, "停止录像", Toast.LENGTH_SHORT).show();
        }
    }

    public void handleStartRecording() {
        mCameraHandler = CameraHandler.createHandler(this, BaseConstants.DEFAULT_HEIGHT, BaseConstants.DEFAULT_WIDTH);
        mCameraHandler.startRecording();
    }

    public void handleStopRecording() {
        Log.i(TAG, "handleStopRecording:mMuxer=");
        mCameraHandler.stopRecording();
        mCameraHandler = null;
    }

}
